﻿// Decompiled with JetBrains decompiler
// Type: DnProcessSimulateCommands.CApDataFileWriter
// Assembly: DnProcessSimulateCommands, Version=2402.0.0.890, Culture=neutral, PublicKeyToken=null
// MVID: A885D881-AEDF-447E-852A-6F13102E089C
// Assembly location: C:\Program Files\Tecnomatix_2402\eMPower\DotNetCommands\DnProcessSimulateCommands.dll

using EngineeringInternalExtension;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Drawing;
using System.Globalization;
using System.Text;
using System.Xml;
using Tecnomatix.Engineering;


namespace DnProcessSimulateCommands;

internal class CApDataFileWriter : CApXMLFileWriter
{
  private XmlElement m_objectsElement;
  private XmlElement m_notesElement;
  private XmlElement m_stepsElement;
  private XmlElement m_viewsElement;
  private NumberFormatInfo m_numberInfo = CultureInfo.InvariantCulture.NumberFormat;
  private CApC3DAppearanceSet m_appearancesSet;

  internal CApDataFileWriter(string filePath)
    : base(filePath)
  {
  }

  internal void Initialize(
    TxExportGraphicsAnimationOutputData animationOutputData,
    CApC3DDocumentationSettings documentationSettings,
    CApC3DAppearanceSet appearancesSet)
  {
    this.Initialize(animationOutputData, documentationSettings);
    this.m_rootElement = this.m_document.CreateElement(CApDataFileDefinitions.AnimationInfoElement);
    this.m_document.AppendChild((XmlNode) this.m_rootElement);
    this.m_objectsElement = this.AddUniqueChild(this.m_rootElement, CApDataFileDefinitions.ObjectsElement, CApDataFileDefinitions.ObjectsComment);
    this.m_notesElement = this.AddUniqueChild(this.m_rootElement, CApDataFileDefinitions.NotesElement, CApDataFileDefinitions.NotesComment);
    this.m_stepsElement = this.AddUniqueChild(this.m_rootElement, CApDataFileDefinitions.StepsElement, CApDataFileDefinitions.StepsComment);
    this.m_viewsElement = this.AddUniqueChild(this.m_rootElement, CApDataFileDefinitions.ViewsElement, CApDataFileDefinitions.ViewsComment);
    this.m_appearancesSet = appearancesSet;
  }

  internal void AddAllObjects(TxExportGraphicsAnimationFileFormatEx fileFormat)
  {
    foreach (TxGraphicsAnimationExportedNode exportedNode in this.m_animationOutputData.ExportedNodes)
    {
      ITxObject objectId = exportedNode.ObjectId;
      if (objectId != null)
      {
        if (objectId is TxNote && objectId.Collection == TxApplication.ActiveDocument.PhysicalRoot && this.m_documentationSettings.PdfMode == null)
          this.AddNote(objectId as TxNote);
        else
          this.AddObject(exportedNode);
      }
    }
  }

  private void AddObject(TxGraphicsAnimationExportedNode exportedNode)
  {
    XmlElement xmlElement = this.CreateObject(exportedNode, this.m_objectsElement);
    string str = exportedNode.ExportedName ?? exportedNode.ObjectId.Name;
    xmlElement.SetAttribute(CApDataFileDefinitions.NameAttribute, str);
  }

  private XmlElement CreateObject(TxGraphicsAnimationExportedNode exportedNode, XmlElement parent)
  {
    string objectId = CApC3DUtils.GetObjectId(exportedNode.ObjectId, exportedNode.ViewId);
    return this.SetUniqueChildAttribute(parent, CApDataFileDefinitions.ObjectElement, CApDataFileDefinitions.IdAttribute, objectId);
  }

  private void AddNote(TxNote note)
  {
    XmlElement note1 = this.CreateNote(note, this.m_notesElement);
    ITxObject assignedObject = (ITxObject) note.AssignedObject;
    string str1 = "";
    if (assignedObject != null)
      str1 = CApC3DUtils.GetObjectId(assignedObject);
    this.SetUniqueChildValue(note1, CApDataFileDefinitions.AttachedObjectElement, str1);
    XmlElement parent = this.AddChild(note1, CApDataFileDefinitions.TextElement);
    int num = 0;
    string text = note.Text;
    ArrayList arrayList = new ArrayList();
    string str2 = text;
    char[] chArray = new char[1]{ '\n' };
    foreach (string str3 in str2.Split(chArray))
    {
      if (str3.Trim() != "")
      {
        this.SetChildValue(parent, CApDataFileDefinitions.LineElement, str3, true);
        ++num;
      }
    }
    parent.SetAttribute(CApDataFileDefinitions.LinesAttribute, num.ToString());
    this.AddTextDirectionData(note1, note.RightToLeft);
  }

  private XmlElement CreateNote(TxNote note, XmlElement parent)
  {
    string objectId = CApC3DUtils.GetObjectId((ITxObject) note);
    return this.SetUniqueChildAttribute(parent, CApDataFileDefinitions.NoteElement, CApDataFileDefinitions.IdAttribute, objectId);
  }

  internal void AddStep(ITxObject obj, TxSnapshot snapshot)
  {
    string objectId = CApC3DUtils.GetObjectId(obj);
    string str = "";
    if (TxSnapshot.op_Inequality(snapshot, (ITxObject) null))
      str = CApC3DUtils.GetObjectId((ITxObject) snapshot);
    this.SetUniqueChildAttribute(this.m_stepsElement, CApDataFileDefinitions.StepElement, CApDataFileDefinitions.IdAttribute, objectId).SetAttribute(CApDataFileDefinitions.ViewIdAttribute, str);
  }

  internal bool AddView(CApC3DSnapshotNodeData snapshotData)
  {
    bool flag = false;
    string objectId = CApC3DUtils.GetObjectId((ITxObject) snapshotData.Snapshot);
    if (this.FindElement(this.m_viewsElement, CApDataFileDefinitions.ViewElement, CApDataFileDefinitions.IdAttribute, objectId) == null)
    {
      flag = true;
      XmlElement viewEl = this.SetUniqueChildAttribute(this.m_viewsElement, CApDataFileDefinitions.ViewElement, CApDataFileDefinitions.IdAttribute, objectId);
      viewEl.SetAttribute(CApDataFileDefinitions.NameAttribute, snapshotData.Name);
      viewEl.SetAttribute(CApDataFileDefinitions.DisplayNameAttribute, snapshotData.DisplayName);
      this.FillViewInformation(snapshotData.Snapshot, viewEl);
    }
    return flag;
  }

  private void FillViewInformation(TxSnapshot snapshot, XmlElement viewEl)
  {
    this.AddViewProjectionTypeData(viewEl);
    this.AddViewCameraData(viewEl);
    this.AddViewRectangleData(viewEl);
    this.AddViewAllDisplayedObjectsData(viewEl, snapshot);
  }

  private void FillObjectData(
    ITxDisplayableObject dispObj,
    TxDisplayMode displayMode,
    XmlElement objectEl)
  {
    TxNote txNote = dispObj as TxNote;
    if (TxNote.op_Inequality(txNote, (ITxObject) null) && this.m_documentationSettings.PdfMode == 1)
    {
      this.AddNoteTransformationData(objectEl, txNote);
    }
    else
    {
      this.AddObjectTransformationData(objectEl, (ITxObject) dispObj);
      this.AddObjectOpacityData(objectEl, (ITxObject) dispObj);
      this.AddObjectViewModeData(objectEl, (ITxObject) dispObj, displayMode);
      this.AddObjectColorData(objectEl, (ITxObject) dispObj);
    }
  }

  private void FillNoteData(TxNote note, XmlElement noteEl)
  {
    this.AddAnnotationStartPointData(noteEl, (ITxLocatableObject) note);
    this.AddNoteEndPointData(noteEl, note);
    this.AddFontData(noteEl, note.Font);
  }

  private void FillPmiData(TxPmi pmi, XmlElement pmiEl)
  {
    this.AddAnnotationStartPointData(pmiEl, (ITxLocatableObject) pmi);
    this.AddPmiEndPointData(pmiEl, pmi);
  }

  private string CalculateTransformation(
    TxVector position,
    TxVector referencePoint,
    TxVector upVector)
  {
    TxVector txVector1 = TxVector.op_Subtraction(referencePoint, position);
    txVector1.Normalize();
    TxVector txVector2 = TxVector.CrossProduct(upVector, txVector1);
    txVector2.Normalize();
    TxVector txVector3 = TxVector.CrossProduct(txVector1, txVector2);
    StringBuilder stringBuilder = new StringBuilder();
    stringBuilder.AppendFormat("{0} {1} {2} {3} {4} {5} {6} {7} {8} {9} {10} {11}", (object) txVector2.X.ToString((IFormatProvider) this.m_numberInfo), (object) txVector2.Y.ToString((IFormatProvider) this.m_numberInfo), (object) txVector2.Z.ToString((IFormatProvider) this.m_numberInfo), (object) txVector3.X.ToString((IFormatProvider) this.m_numberInfo), (object) txVector3.Y.ToString((IFormatProvider) this.m_numberInfo), (object) txVector3.Z.ToString((IFormatProvider) this.m_numberInfo), (object) txVector1.X.ToString((IFormatProvider) this.m_numberInfo), (object) txVector1.Y.ToString((IFormatProvider) this.m_numberInfo), (object) txVector1.Z.ToString((IFormatProvider) this.m_numberInfo), (object) position.X.ToString((IFormatProvider) this.m_numberInfo), (object) position.Y.ToString((IFormatProvider) this.m_numberInfo), (object) position.Z.ToString((IFormatProvider) this.m_numberInfo));
    return stringBuilder.ToString();
  }

  private void SetAllSnapshots(bool allSnapshots)
  {
    string str = allSnapshots ? CApDataFileDefinitions.TrueValue : CApDataFileDefinitions.FalseValue;
    this.m_viewsElement.SetAttribute(CApDataFileDefinitions.AllSnapshotsAttribute, str);
  }

  private void SetHaveAnimation(bool haveAnimation)
  {
    string str = haveAnimation ? CApDataFileDefinitions.TrueValue : CApDataFileDefinitions.FalseValue;
    this.m_viewsElement.SetAttribute(CApDataFileDefinitions.AnimationAttribute, str);
  }

  private void SetCompressData(bool compressData)
  {
    string str = compressData ? CApDataFileDefinitions.TrueValue : CApDataFileDefinitions.FalseValue;
    this.m_viewsElement.SetAttribute(CApDataFileDefinitions.CompressDataAttribute, str);
  }

  private void SetIncludePMIs(bool includePMIs)
  {
    string str = includePMIs ? CApDataFileDefinitions.TrueValue : CApDataFileDefinitions.FalseValue;
    this.m_viewsElement.SetAttribute(CApDataFileDefinitions.IncludePMIsAttribute, str);
  }

  private void SetPdfMode(TxExportGraphicsAnimationFileFormatEx pdfMode)
  {
    string empty = string.Empty;
    string str = pdfMode == null ? CApDataFileDefinitions.PdfModeU3DAttributeValue : (pdfMode == 1 ? CApDataFileDefinitions.PdfModePRCAttributeValue : string.Empty);
    this.m_viewsElement.SetAttribute(CApDataFileDefinitions.PdfModeAttribute, str);
  }

  private void SetIncludedObjectsMode(
    CApC3DDocumentationSettings.CApC3DIncludedObjectsMode includedObjectsMode)
  {
    string empty = string.Empty;
    string str;
    switch (includedObjectsMode)
    {
      case CApC3DDocumentationSettings.CApC3DIncludedObjectsMode.OnlyDisplayedObjectsInScene:
        str = CApDataFileDefinitions.OnlyDisplayedObjectsInSceneAttributeValue;
        break;
      case CApC3DDocumentationSettings.CApC3DIncludedObjectsMode.OnlyObjectsIncludedInSnapshotsAndSimulation:
        str = CApDataFileDefinitions.OnlyObjectsIncludedInSnapshotsAttributeValue;
        break;
      case CApC3DDocumentationSettings.CApC3DIncludedObjectsMode.AllLoadedObjects:
        str = CApDataFileDefinitions.AllObjectsInSceneAttributeValue;
        break;
      default:
        str = string.Empty;
        break;
    }
    this.m_viewsElement.SetAttribute(CApDataFileDefinitions.IncludedObjectsMode, str);
  }

  private void SetIncludeDisplayedPartsMode()
  {
    this.m_viewsElement.SetAttribute(CApDataFileDefinitions.IncludeDisplayedPartsAttribute, false.ToString());
  }

  internal void SetDocumentationSettings(CApC3DDocumentationSettings documentationSettings)
  {
    this.SetAllSnapshots(documentationSettings.StoreAllSnapshots);
    this.SetHaveAnimation(documentationSettings.RecordAnimation);
    this.SetCompressData(documentationSettings.Compress3DDocuments);
    this.SetIncludePMIs(documentationSettings.IncludePMIs);
    this.SetPdfMode(documentationSettings.PdfMode);
    this.SetIncludedObjectsMode(documentationSettings.IncludedObjectsMode);
    this.SetIncludeDisplayedPartsMode();
  }

  private void AddObjectOpacityData(XmlElement element, ITxObject obj)
  {
    double num = Math.Round((double) TxEngineeringDataInternal.GetTransparency(obj), 2);
    this.SetUniqueChildValue(element, CApDataFileDefinitions.OpacityElement, num.ToString((IFormatProvider) this.m_numberInfo));
  }

  private void AddObjectTransformationData(XmlElement element, ITxObject obj)
  {
    if (!(obj is ITxLocatableObject itxLocatableObject) || !(((ITxObject) itxLocatableObject).Collection is ITxLocatableObject collection))
      return;
    TxTransformation relativeToObject = itxLocatableObject.GetLocationRelativeToObject(collection);
    this.SetUniqueChildValue(element, relativeToObject);
  }

  private void SetUniqueChildValue(XmlElement parentElement, TxTransformation location)
  {
    string str1 = "";
    string str2 = "";
    double num;
    for (int index1 = 0; index1 < 4; ++index1)
    {
      for (int index2 = 0; index2 < 3; ++index2)
      {
        if (index1 < 3)
        {
          string str3 = str1;
          num = Math.Round(location[index2, index1], 3);
          string str4 = num.ToString();
          str1 = str3 + str4 + " ";
        }
        else if (index1 == 3)
        {
          string str5 = str2;
          num = Math.Round(location[index2, index1], 3);
          string str6 = num.ToString();
          str2 = str5 + str6 + " ";
        }
      }
    }
    string str7 = str1 + str2;
    this.SetUniqueChildValue(parentElement, CApDataFileDefinitions.TransformationElement, CApDataFileDefinitions.ObjectComment, str7);
  }

  private void AddNoteTransformationData(XmlElement element, TxNote obj)
  {
    TxVector relativePosition = obj.FlagRelativePosition;
    TxTransformation vecRotation = new TxTransformation().MapVecToVecRotation(new TxVector(1.0, 0.0, 0.0), relativePosition);
    double num = Math.Sqrt(TxVector.DotProduct(relativePosition, relativePosition));
    TxTransformation location = TxTransformation.op_Multiply(TxTransformation.op_Multiply(obj.AbsoluteLocation, vecRotation), new TxTransformation()
    {
      [0, 0] = num,
      [1, 1] = num,
      [2, 2] = num
    });
    this.SetUniqueChildValue(element, location);
  }

  private void AddObjectColorData(XmlElement element, ITxObject obj)
  {
    if (!(obj is ITxDisplayableObject displayableObject))
      return;
    TxColor color;
    try
    {
      color = displayableObject.Color;
    }
    catch (TxException ex)
    {
      color = (TxColor) null;
    }
    if (!TxColor.op_Inequality(color, (TxColor) null))
      return;
    this.AddColorData(element, color);
  }

  private void AddObjectViewModeData(XmlElement element, ITxObject obj, TxDisplayMode displayMode)
  {
    this.SetUniqueChildValue(element, CApDataFileDefinitions.DisplayMode, CApDataFileDefinitions.DisplayModeComment, displayMode.ToString());
  }

  private void AddViewProjectionTypeData(XmlElement element)
  {
    string str = "";
    TxProjectionType projectionType = TxGraphicViewerEx.The.ProjectionType;
    if (projectionType != null)
    {
      if (projectionType == 1)
        str = CApDataFileDefinitions.PerspectiveValue;
    }
    else
      str = CApDataFileDefinitions.ParallelValue;
    this.SetUniqueChildValue(element, CApDataFileDefinitions.ProjectionTypeElement, str);
  }

  private void AddViewCameraData(XmlElement element)
  {
    TxCamera currentCamera = TxApplication.ViewersManager.GraphicViewer.CurrentCamera;
    string transformation = this.CalculateTransformation(currentCamera.Position, currentCamera.ReferencePoint, currentCamera.UpVector);
    this.SetUniqueChildValue(element, CApDataFileDefinitions.CameraTransformationElement, CApDataFileDefinitions.CameraComment, transformation);
    double num = Math.Sqrt(TxVector.op_Multiply(TxVector.op_Subtraction(currentCamera.ReferencePoint, currentCamera.Position), TxVector.op_Subtraction(currentCamera.ReferencePoint, currentCamera.Position)));
    this.SetUniqueChildValue(element, CApDataFileDefinitions.CameraDistanceToReferencePointElement, num.ToString());
  }

  private void AddViewRectangleData(XmlElement element)
  {
    RectangleF viewRectangle = TxApplication.ViewersManager.GraphicViewer.ViewRectangle;
    XmlElement parent = this.AddUniqueChild(element, CApDataFileDefinitions.RectangleElement, CApDataFileDefinitions.RectangleComment);
    this.SetChildValue(parent, CApDataFileDefinitions.LeftElement, viewRectangle.Left.ToString((IFormatProvider) this.m_numberInfo), false);
    this.SetChildValue(parent, CApDataFileDefinitions.RightElement, viewRectangle.Right.ToString((IFormatProvider) this.m_numberInfo), false);
    this.SetChildValue(parent, CApDataFileDefinitions.TopElement, viewRectangle.Top.ToString((IFormatProvider) this.m_numberInfo), false);
    this.SetChildValue(parent, CApDataFileDefinitions.BottomElement, viewRectangle.Bottom.ToString((IFormatProvider) this.m_numberInfo), false);
  }

  private void AddViewAllDisplayedObjectsData(XmlElement element, TxSnapshot snapshot)
  {
    XmlElement parent1 = this.AddUniqueChild(element, CApDataFileDefinitions.VisibleObjectsElement, CApDataFileDefinitions.VisibleObjectsComment);
    XmlElement parent2 = this.AddUniqueChild(element, CApDataFileDefinitions.VisibleNotesElement, CApDataFileDefinitions.VisibleNotesComment);
    ArrayList objectsWithDisplayMode = TxEngineeringDataInternal.CellGetObjectsWithDisplayMode();
    Dictionary<ITxObject, TxDisplayMode> dictionary = new Dictionary<ITxObject, TxDisplayMode>();
    if (objectsWithDisplayMode != null)
    {
      foreach (TxObjectDisplayModeData objectDisplayModeData in objectsWithDisplayMode)
        dictionary.Add((ITxObject) objectDisplayModeData.Object, objectDisplayModeData.DisplayMode);
    }
    foreach (TxGraphicsAnimationExportedNode exportedNode in this.m_animationOutputData.ExportedNodes)
    {
      ITxObject objectId = exportedNode.ObjectId;
      if (objectId is ITxDisplayableObject)
      {
        ITxDisplayableObject dispObj = objectId as ITxDisplayableObject;
        TxDisplayableObjectVisibility visibility = dispObj.Visibility;
        if (visibility == null || visibility == 1)
        {
          CApC3DAppearance appearance = this.m_appearancesSet.GetAppearance(exportedNode.ObjectId as ITxDisplayableObject, exportedNode.ViewId);
          if (appearance == null || appearance.DoesExistInSnapshot(snapshot))
          {
            if (objectId is TxNote && !TxObjectEx.HasPMIType(objectId) && this.m_documentationSettings.PdfMode == null)
            {
              TxNote note1 = objectId as TxNote;
              XmlElement note2 = this.CreateNote(note1, parent2);
              this.FillNoteData(note1, note2);
            }
            else
            {
              XmlElement xmlElement = this.CreateObject(exportedNode, parent1);
              TxDisplayMode displayMode = (TxDisplayMode) 1;
              if (dictionary.ContainsKey(objectId))
              {
                displayMode = dictionary[objectId];
              }
              else
              {
                foreach (ITxObject objectParent in (Collection<ITxObject>) this.GetObjectParents(objectId))
                {
                  if (dictionary.ContainsKey(objectParent))
                  {
                    displayMode = dictionary[objectParent];
                    break;
                  }
                }
              }
              if (objectId is TxPmi)
                this.FillPmiData(objectId as TxPmi, xmlElement);
              else
                this.FillObjectData(dispObj, displayMode, xmlElement);
            }
          }
        }
      }
    }
  }

  private TxObjectList GetObjectParents(ITxObject obj)
  {
    TxObjectList objectParents = new TxObjectList();
    for (ITxObject collection = (ITxObject) obj.Collection; collection != null; collection = (ITxObject) collection.Collection)
      ((Collection<ITxObject>) objectParents).Add(collection);
    return objectParents;
  }

  private void AddColorData(XmlElement element, TxColor color)
  {
    this.AddColorData(element, color, CApDataFileDefinitions.ColorElement);
  }

  private void AddTextDirectionData(XmlElement element, bool rightToLeft)
  {
    this.SetUniqueChildValue(element, CApDataFileDefinitions.RightToLeft, rightToLeft.ToString());
  }

  private void AddBackgroundColorData(XmlElement element, TxColor color)
  {
    this.AddColorData(element, color, CApDataFileDefinitions.BackgroundColorElement);
  }

  private void AddColorData(XmlElement element, TxColor color, string colorType)
  {
    XmlElement parent = this.AddUniqueChild(element, colorType);
    this.SetChildValue(parent, CApDataFileDefinitions.RElement, color.Red.ToString(), false);
    this.SetChildValue(parent, CApDataFileDefinitions.GElement, color.Green.ToString(), false);
    this.SetChildValue(parent, CApDataFileDefinitions.BElement, color.Blue.ToString(), false);
  }

  private void AddPointData(XmlElement element, TxVector point, string pointType, string comment)
  {
    XmlElement parent = this.AddUniqueChild(element, pointType, comment);
    this.SetChildValue(parent, CApDataFileDefinitions.XElement, point.X.ToString((IFormatProvider) this.m_numberInfo), false);
    this.SetChildValue(parent, CApDataFileDefinitions.YElement, point.Y.ToString((IFormatProvider) this.m_numberInfo), false);
    this.SetChildValue(parent, CApDataFileDefinitions.ZElement, point.Z.ToString((IFormatProvider) this.m_numberInfo), false);
  }

  private void AddAnnotationStartPointData(XmlElement element, ITxLocatableObject annotation)
  {
    TxVector translation = annotation.AbsoluteLocation.Translation;
    this.AddPointData(element, translation, CApDataFileDefinitions.StartPointElement, CApDataFileDefinitions.StartAnnotationComment);
  }

  private void AddNoteEndPointData(XmlElement element, TxNote note)
  {
    TxTransformation txTransformation = new TxTransformation(note.FlagRelativePosition, (TxTransformation.TxTransformationType) 1);
    TxVector translation = TxTransformation.op_Multiply(note.AbsoluteLocation, txTransformation).Translation;
    this.AddPointData(element, translation, CApDataFileDefinitions.RelativeEndPointElement, CApDataFileDefinitions.EndAnnotationComment);
  }

  private void AddPmiEndPointData(XmlElement element, TxPmi pmi)
  {
    TxTransformation txTransformation = new TxTransformation(pmi.FlagRelativePosition, (TxTransformation.TxTransformationType) 1);
    TxVector translation = TxTransformation.op_Multiply(pmi.AbsoluteLocation, txTransformation).Translation;
    this.AddPointData(element, translation, CApDataFileDefinitions.RelativeEndPointElement, CApDataFileDefinitions.EndAnnotationComment);
  }

  private void AddFontData(XmlElement element, TxFont font)
  {
    this.SetUniqueChildValue(this.AddUniqueChild(element, CApDataFileDefinitions.FontElement), CApDataFileDefinitions.SizeElement, font.SizeInPoints.ToString());
  }
}
